<template>
  <el-dialog :model-value="modelValue" @close="close()" draggable :title="title" top="5vh">
    <el-input v-model="filterText" placeholder="请输入名称，按回车键【Enter】查询" />
    <el-scrollbar height="70vh">
      <el-tree ref="treeRef" :data="userMenuList" show-checkbox node-key="id" default-expand-all
        :expand-on-click-node="false" :check-on-click-node="true" :props="{
          children: 'children',
          label: 'name',
          disabled: 'isRoleMenu',
        }" :default-checked-keys="selectMenuIdList" :filter-node-method="filterNode" @check="menuChange"
        :check-strictly="true">
        <template #default="{ node, data }">
          <span>
            <el-tag size="small" :type="data.menuType === MenuTypeEnum.Group
                ? 'success'
                : data.menuType === MenuTypeEnum.Menu
                  ? 'danger'
                  : data.menuType === MenuTypeEnum.List
                    ? 'warning'
                    : 'primary'
              ">
              {{ menuTypeFilter(data) }}
            </el-tag>
            <span>【{{ node.label }}】</span>
            <span v-if="data.isRoleMenu">【已通过角色分配】</span>
          </span>
        </template>
      </el-tree>
    </el-scrollbar>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="close()">取消</el-button>
        <el-button type="primary" @click="saveForm()" v-button="['api:sys:sysusermenu:create']">
          确认
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import UserMenuApi, { UserMenu, UserMenuCreate } from "@/api/sys/user/userMenu";
import EnumApi, { EnumData } from "@/api/enums";
import { MenuTypeEnum } from "@/enums/MenuTypeEnum";

const treeRef = ref(ElTree);
const props = defineProps({
  modelValue: Boolean,
  info: Object,
  userId: String,
  title: String,
});

onMounted(async () => {
  await query();
  await getMenuTypeList();
});

const emits = defineEmits(["update:modelValue", "success"]);

const userMenuList = ref<UserMenu[]>([]);
const selectMenuIdList = ref([]);

const query = async () => {
  const { dataList, dataExt } = await UserMenuApi.query(props.userId);
  userMenuList.value = dataList;
  selectMenuIdList.value = dataExt;
};

const menuTypeList = ref<EnumData[]>([]);
const getMenuTypeList = async () => {
  menuTypeList.value = await EnumApi.QueryMenuTypeEnums();
};

const menuChange = (menu: UserMenu) => {
  const childIds = [menu.id];
  treeToList(childIds, menu.children);
  if (selectMenuIdList.value.indexOf(menu.id) !== -1) {
    for (let i = 0; i < childIds.length; i++) {
      const index = selectMenuIdList.value.indexOf(childIds[i]);
      if (index !== -1) {
        selectMenuIdList.value.splice(index, 1);
      }
    }
  } else {
    for (let i = 0; i < childIds.length; i++) {
      const index = selectMenuIdList.value.indexOf(childIds[i]);
      if (index === -1) {
        selectMenuIdList.value.push(childIds[i]);
      }
    }
  }
  treeRef.value.setCheckedKeys(selectMenuIdList.value);
};

const treeToList = (menuIds: String[], menu: UserMenu[]) => {
  if (menu) {
    menu.forEach((element) => {
      menuIds.push(element.id);
      if (element.children && element.children.length > 0) {
        treeToList(menuIds, element.children);
      }
    });
  }
};

const menuTypeFilter = computed(() => (item: UserMenu) => {
  return menuTypeList.value.find((x) => x.value === item.menuType)?.text;
});

const filterText = ref("");

watch(filterText, (val) => {
  treeRef.value!.filter(val);
});

const filterNode = (value: string, data: UserMenu) => {
  if (!value) return true;
  return data.name.includes(value);
};

//提交数据
const userMenu = ref<UserMenuCreate>({
  userId: "",
  menuIdList: [],
});
const saveForm = async () => {
  userMenu.value.userId = props.userId;
  userMenu.value.menuIdList = treeRef.value.getCheckedNodes(false, true).map((x) => x.id);
  const { success, message } = await UserMenuApi.create(userMenu.value);
  if (success) {
    emits("success");
    ElNotification({
      title: message,
      type: "success",
    });
    close();
  } else {
    ElNotification({
      title: message,
      type: "error",
    });
  }
};

const close = () => {
  emits("update:modelValue");
};
</script>
